/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package net.ytbolg.mcxa.gui;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.FileChannel;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import sun.java2d.loops.CompositeType;

/**
 *
 * @author Ytong
 */
public class CommonTools {

    public static String getSys() throws IOException {
        String tmp = System.getProperty("os.name");
        if (tmp.contains("Windows")) {
            return "windows";
        }
        if (tmp.contains("Linux")) {
            return "linux";
        }
        if (tmp.contains("Mac")) {
            return "osx";
        }
        throw new IOException("未知系统！");
    }

    public static String ReadFile(String path) throws FileNotFoundException, IOException {

        File file = new File(path);
        FileReader r = new FileReader(file);
        char c[] = new char[(int) file.length()];
        r.read(c);
        r.close();
        return String.valueOf(c);
    }

    abstract class MCInfo {

        public abstract String getVersionType();

        public abstract String getRelTime();
    }

    public static MCInfo getMCInfo(String ver) {
        try {
            MCInfo m = null;
            final JSONObject jo = new JSONObject(ReadFile(General.GameDir + General.separator + "/versions/" + ver + "/" + ver + ".json"));
            m = new MCInfoImpl(jo);
            return m;
            //return m;
        } catch (JSONException ex) {
            Logger.getLogger(CommonTools.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(CommonTools.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public static String[] ListMinecraftVersions(File GameDir) throws IOException {

        net.ytbolg.mcxa.gui.General.Log( "列"+GameDir.toString(),"CommonTools");
        File versions = new File(GameDir.toString() + "/versions");
        return versions.list(new FilenameFilter() {

            @Override
            public boolean accept(File dir, String name) {
                if (new File(dir.toString() + General.separator + name + General.separator + name + ".jar").exists() && new File(dir.toString() + General.separator + name + General.separator + name + ".json").exists()) {
                    return true;
                }
                General.Log("找到" + dir.toString() + General.separator + name + ",但在其下没有发现" + name + ".jar或" + name + ".json", CommonTools.class.getSimpleName());
                return false;
//  throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }
        });
    }

    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();

            for (String children1 : children) {
                boolean success = deleteDir(new File(dir, children1));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空，可以删除
        return dir.delete();
    }

    public static String getUUIDFromMojang(String name) {
        try {
            URLConnection hc = new URL("https://api.mojang.com/profiles/minecraft").openConnection();
            HttpURLConnection huc = (HttpURLConnection) hc;
            huc.connect();
            huc.setRequestProperty("accept", "*/*");
            huc.setRequestProperty("connection", "Keep-Alive");
            huc.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            huc.setRequestProperty("Content-Type", "application/json");
            huc.setDoInput(true);
            huc.setDoInput(true);
            huc.getOutputStream().write(("[\"" + name + "\"]").getBytes());

            InputStreamReader is = new InputStreamReader(huc.getInputStream());
            StringBuilder sb = new StringBuilder();
            int b = 0;
            while ((b = is.read()) != -1) {
                sb.append(b);
            }
            is.close();
            return new JSONArray(sb.toString()).getString(0);
        } catch (MalformedURLException ex) {
            Logger.getLogger(CommonTools.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(CommonTools.class.getName()).log(Level.SEVERE, null, ex);
            return UUID.fromString(name).toString();
        } catch (JSONException ex) {
            Logger.getLogger(CommonTools.class.getName()).log(Level.SEVERE, null, ex);
        }
        return UUID.fromString(name).toString();
    }

    public static void fileChannelCopy(File s, File t) {

        FileInputStream fi = null;

        FileOutputStream fo = null;

        FileChannel in = null;

        FileChannel out = null;

        try {
            t.getParentFile().mkdirs();
            if (t.exists() == false) {
                t.createNewFile();
            }
            fi = new FileInputStream(s);

            fo = new FileOutputStream(t);

            in = fi.getChannel();//得到对应的文件通道

            out = fo.getChannel();//得到对应的文件通道

            in.transferTo(0, in.size(), out);//连接两个通道，并且从in通道读取，然后写入out通道

        } catch (IOException e) {

            e.printStackTrace();

        } finally {

            try {

                fi.close();

                in.close();

                fo.close();

                out.close();

            } catch (IOException e) {

                e.printStackTrace();

            }

        }

    }

    public static String URLToString(String remoteFilePath) throws IOException {
        General.Log("下载" + remoteFilePath + "中", CommonTools.class.getSimpleName());
        URL urlfile = null;
        HttpURLConnection httpUrl = null;
        BufferedInputStream bis = null;
        //  BufferedOutputStream bos = null;

//      f.mkdirs();
        try {
            StringBuilder sb = new StringBuilder();
            urlfile = new URL(remoteFilePath);
            httpUrl = (HttpURLConnection) urlfile.openConnection();
            httpUrl.connect();
            //   bis = new BufferedInputStream(httpUrl.getInputStream());
            InputStreamReader isr = new InputStreamReader(httpUrl.getInputStream());
            //    bos = new BufferedOutputStream(new FileOutputStream(f));
            int len = 0;
            //byte[] b = new byte[len];
            while ((len = isr.read()) != -1) {
                //        bos.write(b, 0, len);
                sb.append((char) len);
            }
            //   bos.flush();
            isr.close();
// bis.close();
            httpUrl.disconnect();
            return sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null, "无法下载"+remoteFilePath);
            return "";
        }

    }

    public static void downloadFile(String remoteFilePath, String localFilePath) {
        URL urlfile = null;
        HttpURLConnection httpUrl = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        File f = new File(localFilePath);
        File xxxx = new File(f.getParent());
        xxxx.mkdirs();
        General.Log("下载" + remoteFilePath + "到" + localFilePath + "中", CommonTools.class.getSimpleName());
//      f.mkdirs();
        try {
            urlfile = new URL(remoteFilePath);
            httpUrl = (HttpURLConnection) urlfile.openConnection();
            httpUrl.connect();
            //j.setMaximum(httpUrl.getContentLength());
            //j.setValue(0);
            bis = new BufferedInputStream(httpUrl.getInputStream());
            bos = new BufferedOutputStream(new FileOutputStream(f));
            int len = 2048;
            byte[] b = new byte[len];
            int i = 0;
            while ((len = bis.read(b)) != -1) {
                i = i + len;
                //  j.setValue(i);
                //l.setText(i / 1024 + "/" + (httpUrl.getContentLength() / 1024) + "KB");
                bos.write(b, 0, len);
            }
            bos.flush();
            bis.close();
            httpUrl.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                bis.close();
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static class MCInfoImpl extends MCInfo {

        private final JSONObject jo;

        public MCInfoImpl(JSONObject jo) {
            this.jo = jo;
        }

        @Override
        public String getVersionType() {
            try {
                return jo.getString("type");
                //     throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            } catch (JSONException ex) {
                Logger.getLogger(CommonTools.class.getName()).log(Level.SEVERE, null, ex);
            }
            return null;
        }

        @Override
        public String getRelTime() {
            try {
                return jo.getString("releaseTime");
                //   return jo.getString("release");    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            } catch (JSONException ex) {
                Logger.getLogger(CommonTools.class.getName()).log(Level.SEVERE, null, ex);
            }
            return null;
        }
    }
}
